#include <iostream>
#include <string>
#include <pthread.h>
#include <unistd.h>
#include <unistd.h>
#include "task.hpp"
#include "circularQueue.hpp"

using std::cout;
using std::endl;

void *consumer(void *args)
{
    // circularQueue<int> *cq = static_cast<circularQueue<int> *>(args);
    circularQueue<Task> *cq = static_cast<circularQueue<Task> *>(args);
    cout << "consumer..." << endl;
    // 是一个循环 -- 你的消费者只执行一次的吗？
    while (true)
    {
        sleep(1);

        // int data = 0;
        // cq->pop(&data);
        // cout << "consumer get data: " << data << endl;

        Task t;
        // 消费者获取数据
        cq->pop(&t);
        // 进行数据处理
        t();
        cout << "consumer get data: " << t.formatExpression() << t.formatResult() << endl;
    }
    return nullptr;
}

void *producer(void *args)
{
    // circularQueue<int> *cq = static_cast<circularQueue<int> *>(args);
    circularQueue<Task> *cq = static_cast<circularQueue<Task> *>(args);

    // 是一个循环 -- 你的生产者者只执行一次的吗？
    std::string ops = "+-*/%";
    while (true)
    {
        sleep(1);
        // 获取数据
        // int data = rand() % 20;
        // cq->push(data);
        // cout << "prodecer push data: " << data << endl;

        int x = rand() & 20;
        int y = rand() % 20;
        char op = ops[rand() % ops.size()];
        Task t(x, y, op);
        // 放入循环队列中
        cq->push(t);
        cout << "prodecer push data: " << t.formatExpression() << "?" << endl;
    }
    return nullptr;
}

int main()
{
    // circularQueue<int>* cq = new circularQueue<int>();
    circularQueue<Task> *cq = new circularQueue<Task>();

    // 让同一份资源被多线程看到 --> 传参
    // 单生产者，单消费者
    // pthread_t c, p;
    // pthread_create(&c, nullptr, consumer, cq);
    // pthread_create(&p, nullptr, producer, cq);

    // pthread_join(c, nullptr);
    // pthread_join(p, nullptr);

    // 多生产多消费
    pthread_t c[2], p[3];
    for (int i = 0; i < 2; i++)
        pthread_create(c + i, nullptr, consumer, cq);
    for (int i = 0; i < 3; i++)
        pthread_create(p + i, nullptr, producer, cq);
    for (int i = 0; i < 2; i++)
        pthread_join(c[i], nullptr);
    for (int i = 0; i < 3; i++)
        pthread_join(p[i], nullptr);

    return 0;
}